package com.yanqu.road.server.manger.activity.cookboy;

import com.yanqu.road.dao.impl.player.UserCommonActivityDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.cookboy.CookBoyData;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoy2Dish;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoy2DishConfig;
import com.yanqu.road.entity.activity.cookboy.process2.CookBoy2Spoon;
import com.yanqu.road.entity.activity.cookboy.process2.PickDishRes;
import com.yanqu.road.entity.autodata.cookboy.CookBoy2AutoJoinSpoon;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.activity.eActivityCookBoyType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.language.LanguageType;
import com.yanqu.road.entity.log.LogCookBoy2FinishFood;
import com.yanqu.road.entity.log.LogCookBoy2PickFood;
import com.yanqu.road.entity.player.UserBagItem;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.relatives.RelativesInfo;
import com.yanqu.road.entity.task.args.RelationActivityUnionRiseRankArgs;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.entity.union.UnionMember;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.bussiness.player.UserCookBoyBussiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.cookboy.CookBoyProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.cookboy.CookBoyModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.relatives.RelativesModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.RelationActivityMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CookBoy2 {

	private Logger logger = LogManager.getLogger(CookBoy2.class.getName());

	private final Map<Long,Object> lockMap = new ConcurrentHashMap<>();

	private ActivityInfo activityInfo;

	//用户id 用户数据
	private Map<Long, CookBoyData> cookBoyDataMap = new ConcurrentHashMap<>();

	private List<CookBoyData> needAddCookBoyList = new ArrayList<>();

	private List<CookBoyData> needUpdateCookBoyList = new ArrayList<>();

	//正在发菜场景的人
	private Map<Long,List<Long>> sceneUserMap = new ConcurrentHashMap<>();

	boolean acOverRecovery = false;

	private long lastChekDishStatusTime;

	private Map<Long, CookBoy2AutoJoinSpoon> autoJoinSpoonMap = new ConcurrentHashMap<>(); // 自动回访汤勺

	public CookBoy2(ActivityInfo acInfo){
		activityInfo = acInfo;
//		reload();
	}

	public Object getLock(long userId){
		synchronized (lockMap){
			if(!lockMap.containsKey(userId)){
				lockMap.put(userId,new Object());
			}
			return lockMap.get(userId);
		}
	}

	public boolean isSceneUser(long userId,long openBanquetUserId){
		for(Long inUserId : sceneUserMap.get(openBanquetUserId)){
			if(inUserId == userId){
				return true;
			}
		}
		return false;
	}
	public Map<Long,CookBoyData> getWindUpUserCookBoyMap(List<Long> userIdList){
		Map<Long,CookBoyData> res = new ConcurrentHashMap<>();
		for(long userId : userIdList){
			if(cookBoyDataMap.containsKey(userId)){
				res.put(userId,cookBoyDataMap.get(userId));
			}
		}
		return res;
	}

	//晋级玩家数据生成
	public boolean windUpCookBoy(List<Long> userIdList){
		boolean isUpdate = false;
		for(Long userId : userIdList){
			if(!cookBoyDataMap.containsKey(userId)){
				cookBoyDataMap.put(userId,initCookBoy2(userId));
			}
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			if(cookBoyData.isAble()){
				continue;
			}
			cookBoyData.setAble(true);
			isUpdate = true;
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			if(player != null){
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}
		}
		return isUpdate;
	}

	public int worship(long userId){
		Object locker = getLock(userId);
		synchronized (locker){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			if(cookBoyData.isWorship()){
				return GameErrorCode.E_COOK_BOY_FOOD_IS_WORSHIP;
			}
			GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
			if(gamePlayer != null){
				cookBoyData.setWorship(true);
				synchronized (needUpdateCookBoyList){
					if(!needUpdateCookBoyList.contains(cookBoyData)){
						needUpdateCookBoyList.add(cookBoyData);
					}
				}
				gamePlayer.getModule(CurrencyModule.class).addCurrency(CookBoyActivityMgr.getWorship2Reward(activityInfo.getActivityId()),eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoyActivityWorship);
			}
		}
		return 0;
	}

	public void addSceneUser(long userId,long openBanquetUserId){
		if(!sceneUserMap.containsKey(openBanquetUserId)){
			sceneUserMap.put(openBanquetUserId,new ArrayList<>());
		}
		for(List<Long> userIdList : sceneUserMap.values()){
			userIdList.remove(userId);
		}
		sceneUserMap.get(openBanquetUserId).add(userId);
	}

	public void removeSceneUser(long userId,long openBanquetUserId){
		if(sceneUserMap.containsKey(openBanquetUserId)){
			sceneUserMap.get(openBanquetUserId).remove(userId);
		}
	}

	public List<Long> getSceneUser(long openBanquetUserId){
		if(sceneUserMap.containsKey(openBanquetUserId)){
			return new ArrayList<>(sceneUserMap.get(openBanquetUserId));
		}
		return new ArrayList<>();
	}

	public void cookBoy2RobotBackMsg(CookBoyProto.CrossCookBoy2RobotJoinBanquetMsg msg){
		long userId = msg.getHomeUserId();
		Object locker = getLock(userId);
		synchronized (locker){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			Map<Integer,CookBoy2Dish> cookBoy2DishMap = cookBoyData.getFinishDishMap();
			CookBoy2Dish cookBoy2Dish = cookBoy2DishMap.get(msg.getUserDishId());
			if(cookBoy2Dish.getStatus() == 0 || cookBoy2Dish.getStatus() == 2 || cookBoy2Dish.getStatus() == 3){
				logger.error(userId + "玩家的" + cookBoy2Dish.getDishId() + "菜已经完成");
				return;
			}
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			cookBoyData.setAllIntegral(cookBoyData.getAllIntegral() + msg.getIntegral());
			cookBoy2Dish.setStatus(2);
			cookBoy2Dish.setIntegral(msg.getAllIntegral());
			cookBoy2Dish.setTableId(msg.getTableId());
			cookBoyData.setFinishDishMap(cookBoy2DishMap);
			if(player != null){
				int integralId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
				String reward = integralId + "=" + msg.getIntegral();
				player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2JoinBanquetOwnerReward);
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}else{
				cookBoyData.setIntegral(cookBoyData.getIntegral() + msg.getIntegral());
			}
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			UserInfo userInfo = UserMgr.getUserInfo(userId);
			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2IntegralUserCrossRank.getValue(),
					new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(msg.getIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));

		}
	}


	public void syncHorseNotice(CookBoyProto.CrossCookBoy2HorseSyncServerMsg msg){
		List<GamePlayer> gamePlayerList = GamePlayerMgr.getAllOnlinePlayer();
		for(GamePlayer player : gamePlayerList){
			CookBoyProto.CookBoy2horseRaceLampSyncMsg.Builder userHorseMsg = CookBoyProto.CookBoy2horseRaceLampSyncMsg.newBuilder();
			for(CookBoyProto.CrossCookBoy2HorseNoticeMsg noticeMsg : msg.getNoticeListList()){
				if(noticeMsg.getUserId() != player.getUserId()){
					CookBoyProto.CookBoy2horseRaceLampTempMsg.Builder tempMsg = CookBoyProto.CookBoy2horseRaceLampTempMsg.newBuilder();
					tempMsg.setUserId(noticeMsg.getUserId());
					tempMsg.setDishId(noticeMsg.getDishId());
					tempMsg.setUserInfo(noticeMsg.getPlayerBaseData());
					userHorseMsg.addNoticeList(tempMsg);
				}
			}
			player.sendPacket(Protocol.U_CROSS_COOK_BOY2_HORSE_NOTICE_SYNC, userHorseMsg);
		}
	}

	public void syncTable(CookBoyProto.CrossCookBoy2TableSyncMsg msg){
		CookBoyProto.CookBoy2UserIdTableRespMsg.Builder userTableMsg = CookBoyProto.CookBoy2UserIdTableRespMsg.newBuilder(msg.getUserTable());
		userTableMsg.setIsSync(true);
		List<Long> notOnlineUserId = new ArrayList<>();
		List<Long> userList = getSceneUser(msg.getUserId());
		for(long userId : userList){
			GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
			if(gamePlayer != null){
				gamePlayer.sendPacket(Protocol.U_COOK_BOY2_GET_TABLE_INFO, userTableMsg);
			}else{
				notOnlineUserId.add(userId);
			}
		}
		for(long userId : notOnlineUserId){
			userList.remove(userId);
		}
	}

	public void syncFoodServe(long userId, CookBoyProto.CookBoy2OpenTableRespMsg msg){
		if(cookBoyDataMap.containsKey(userId)){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			Map<Integer,CookBoy2Dish> cookBoy2DishMap = cookBoyData.getFinishDishMap();
			for(CookBoyProto.CrossCookBoy2FoodTableIdMsg oneMsg : msg.getFoodListList()){
				if(cookBoy2DishMap.containsKey(oneMsg.getUserDishId())){
					cookBoy2DishMap.get(oneMsg.getUserDishId()).setTableId(oneMsg.getTableId());
				}
			}
			cookBoyData.setFinishDishMap(cookBoy2DishMap);
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			if(player != null){
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}
		}
	}

	public void backFoodServe(long userId, CookBoyProto.CookBoy2OpenTableRespMsg msg){
		if(cookBoyDataMap.containsKey(userId)){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			Map<Integer,CookBoy2Dish> cookBoy2DishMap = cookBoyData.getFinishDishMap();
			for(CookBoyProto.CrossCookBoy2FoodTableIdMsg oneMsg : msg.getFoodListList()){
				if(cookBoy2DishMap.containsKey(oneMsg.getUserDishId())){
					if(cookBoy2DishMap.get(oneMsg.getUserDishId()).getStatus() == 1){
						cookBoy2DishMap.get(oneMsg.getUserDishId()).setStatus(0);
					}
				}
			}
			cookBoyData.setFinishDishMap(cookBoy2DishMap);
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			if(player != null){
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}
		}
	}

	public void syncCooker(CookBoyProto.CrossCookBoy2CookerSyncMsg msg){
		for(CookBoyData cookBoyData : cookBoyDataMap.values()){
			if(cookBoyData.isAble()){
				GamePlayer player = GamePlayerMgr.getOnlinePlayer(cookBoyData.getUserId());
				if(player != null){
					CookBoyProto.CookBoy2CookerRespMsg.Builder userTableSyncMsg = CookBoyProto.CookBoy2CookerRespMsg.newBuilder();
					userTableSyncMsg.setRet(0);
					userTableSyncMsg.setActivityId(msg.getActivityId());
					for(CookBoyProto.CrossCookBoy2CookerTempMsg cookerMsg : msg.getCookerListList()){
						CookBoyProto.CookBoy2CookerTempMsg.Builder userTempMsg = CookBoyProto.CookBoy2CookerTempMsg.newBuilder();
						userTempMsg.setServerId(cookerMsg.getServerId());
						userTempMsg.setUserId(cookerMsg.getUserId());
						if(cookerMsg.getCanEat()){
							userTempMsg.setCanEat(!cookerMsg.getNoEatUserIdList().contains(cookBoyData.getUserId()));
						}else{
							userTempMsg.setCanEat(false);
						}
						userTempMsg.setUserInfo(cookerMsg.getUserInfo());
						userTempMsg.setRank(cookerMsg.getRank());
						userTempMsg.setActivityId(msg.getActivityId());
						userTableSyncMsg.addCookerList(userTempMsg);
					}
					player.sendPacket(Protocol.U_COOK_BOY2_GET_TABLE_USER, userTableSyncMsg);
				}
			}
		}
	}

	//有人加入宴会了增加开宴者每道菜的积分
	private void addHomeDishIntegral(long homeUserId,int tableId,long addValue){
		if(cookBoyDataMap.containsKey(homeUserId)){
			CookBoyData cookBoyData = cookBoyDataMap.get(homeUserId);
			Map<Integer,CookBoy2Dish> cookBoy2DishMap = cookBoyData.getFinishDishMap();
			for(CookBoy2Dish cookBoy2Dish : cookBoy2DishMap.values()){
				if(cookBoy2Dish.getTableId() == tableId){
					cookBoy2Dish.setIntegral(cookBoy2Dish.getIntegral() + addValue);
					break;
				}
			}
			cookBoyData.setFinishDishMap(cookBoy2DishMap);
		}
	}

	public void openerBackMsg(long userId,int spoonId,int tableId, int autoJoin){
		Object locker = getLock(userId);
		synchronized (locker){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			CookBoy2Spoon cookBoy2Spoon = CookBoyActivityMgr.getCookBoy2Spoon(activityInfo.getActivityId(),spoonId);
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			cookBoyData.setAllIntegral(cookBoyData.getAllIntegral() + cookBoy2Spoon.getUserIntegral());
			addHomeDishIntegral(userId,tableId,cookBoy2Spoon.getUserIntegral());
			if(player != null){
				int integralId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
				if (autoJoin == 0) { // 主动试吃，摊主直接获取奖励
					String reward = integralId + "=" + cookBoy2Spoon.getUserIntegral();
					player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.CookBoy, eLogMoneyType.CrossCookBoy2JoinBanquetReward);
				}
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}else{
				cookBoyData.setIntegral(cookBoyData.getIntegral() + cookBoy2Spoon.getUserIntegral());
			}
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			UserInfo userInfo = UserMgr.getUserInfo(userId);
			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2IntegralUserCrossRank.getValue(),
					new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(cookBoy2Spoon.getUserIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));
		}
	}

	public String joinerBackMsg(long userId,int spoonId, int autoJoin){
		Object locker = getLock(userId);
		synchronized (locker){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			CookBoy2Spoon cookBoy2Spoon = CookBoyActivityMgr.getCookBoy2Spoon(activityInfo.getActivityId(),spoonId);
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			int integralId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
			String reward = "";
			if (autoJoin == 0) { // 主动试吃，访客直接获取奖励
				player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(cookBoy2Spoon.getConsume()), eLogMoneyType.CookBoy, eLogMoneyType.CrossCookBoy2JoinBanquetConsume);
				reward = integralId + "=" + cookBoy2Spoon.getJoinerIntegral();
				player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.CookBoy, eLogMoneyType.CrossCookBoy2JoinBanquetOwnerReward);
			}
			UserInfo userInfo = UserMgr.getUserInfo(userId);
			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2IntegralUserCrossRank.getValue(),
					new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(cookBoy2Spoon.getJoinerIntegral()),userInfo.getUnionUid(), activityInfo.getActivityId()));
			cookBoyData.setAllIntegral(cookBoyData.getAllIntegral() + cookBoy2Spoon.getJoinerIntegral());
			GamePlayer playerOpener = GamePlayerMgr.getOnlinePlayer(userId);
			if(playerOpener != null){
				playerOpener.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}
			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			return reward;
		}
	}

	//参加宴会
	public void addPromotionUserList(int cook1AcId,List<Long> userIdList,Map<Long,CookBoyData> windUpUserCookBoy1Map) {
		//加入没有更新，表示本服已经更新成功某个活动的晋级了，通知跨服，跨服不在下达晋级，如果通知晋级的同步没了就重新登录
		if(windUpCookBoy(userIdList)){

		}
		CookBoyProto.CrossCookBoy2CookerJoinSyncMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2CookerJoinSyncMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		for(long userId : userIdList){
			CookBoyProto.CrossCookBoyWindUpCookerTempMsg.Builder userMsg = CookBoyProto.CrossCookBoyWindUpCookerTempMsg.newBuilder();
			userMsg.setUserId(userId);
			userMsg.setScore(windUpUserCookBoy1Map.get(userId).getAllIntegral());//不知道哪个前面的活动晋级的
			userMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(UserMgr.getUserInfo(userId), GameServer.getInstance().getServerId())));
			reqMsg.addUserInfoList(userMsg);
		}
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_COOKER_JOIN, reqMsg);
		GamePlayerMgr.sendPacket(0, pbMsg);
	}

	//参加宴会
	public int sendJoinMsg(long userId,long homeUserId,int tableId,int spoonId, int trueActivityId){
		CookBoyProto.CookBoy2JoinTableReqMsg.Builder reqMsg = CookBoyProto.CookBoy2JoinTableReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setUserId(homeUserId);
		reqMsg.setTableId(tableId);
		reqMsg.setSpoonId(spoonId);
		reqMsg.setOtherActivityId(trueActivityId);
		UserInfo userInfo = UserMgr.getUserInfo(userId);
		if (userInfo != null) {
			reqMsg.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId())));
		}
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_JOIN_TABLE, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendServeDish(long userId,List<Integer> dishIdList){
		CookBoyData cookBoyData = cookBoyDataMap.get(userId);
		Map<Integer,CookBoy2Dish> cookBoy2DishMap = cookBoyData.getFinishDishMap();
		for(int id : dishIdList){
			if(!cookBoy2DishMap.containsKey(id)){
				return GameErrorCode.E_COOK_BOY2_DISH_NO_FOUND;
			}
			CookBoy2Dish cookBoy2Dish = cookBoy2DishMap.get(id);
			if(cookBoy2Dish.getStatus() != 0){
				return GameErrorCode.E_COOK_BOY2_DISH_IS_SERVE;
			}
		}
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		if(player != null){
			CookBoyProto.CrossCookBoyServeDishReqMsg.Builder reqMsg = CookBoyProto.CrossCookBoyServeDishReqMsg.newBuilder();
			reqMsg.setActivityId(activityInfo.getActivityId());
			reqMsg.setUserId(userId);
			for(int id : dishIdList){
				CookBoyProto.CrossCookBoyServeDishInfoMsg.Builder dishMsg = CookBoyProto.CrossCookBoyServeDishInfoMsg.newBuilder();
				CookBoy2Dish cookBoy2Dish = cookBoy2DishMap.get(id);
				cookBoy2Dish.setStatus(1);
				dishMsg.setId(id);
				dishMsg.setDishId(cookBoy2Dish.getDishId());
				reqMsg.addDishList(dishMsg);
				CookBoy2DishConfig cookBoy2DishConfig = CookBoyActivityMgr.getDishConfig(activityInfo.getActivityId(),cookBoy2Dish.getDishId());
				AutoLogMgr.add(new LogCookBoy2FinishFood(activityInfo.getActivityId(), userId, cookBoy2Dish.getIndex(), cookBoy2Dish.getDishId(), cookBoy2DishConfig.getQuality(), 1));
			}
			cookBoyData.setFinishDishMap(cookBoy2DishMap);
			reqMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(player.getUserInfo(), GameServer.getInstance().getServerId())));
			YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_SERVE_DISH, reqMsg);
			GamePlayerMgr.sendPacket(userId, pbMsg);
			player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
		}
		synchronized (needUpdateCookBoyList){
			if(!needUpdateCookBoyList.contains(cookBoyData)){
				needUpdateCookBoyList.add(cookBoyData);
			}
		}
		return 0;
	}

	//设置禁止试吃的汤勺类型
	public int sendForbidSpoon(long userId,List<Integer> spoonIdList){
		for(Integer spoonId : spoonIdList){
			CookBoy2Spoon spoon = CookBoyActivityMgr.getCookBoy2Spoon(activityInfo.getActivityId(),spoonId);
			if(spoon == null){
				return GameErrorCode.E_COOK_BOY2_SPOON_NOT_FOUND;
			}
		}
		CookBoyProto.CookBoy2ForbidSpoonReqMsg.Builder reqMsg = CookBoyProto.CookBoy2ForbidSpoonReqMsg.newBuilder();
		reqMsg.setActivityId(getActivityInfo().getActivityId());
		reqMsg.addAllSpoonId(spoonIdList);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_FROBID_SPOON, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendCookerHomeMsg(long userId,long homeUserId,int page,int num){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CrossCookBoy2CookerHomeReqMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2CookerHomeReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setUserId(homeUserId);
		reqMsg.setPage(page);
		reqMsg.setNum(num);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_COOKER_HOME, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendCookerTableMsg(long userId,long homeUserId,int tableId){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CrossCookBoy2CookerTableReqMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2CookerTableReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setUserId(homeUserId);
		reqMsg.setTableId(tableId);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_USER_TABLE_INFO, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendCookerMsg(long userId){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CrossCookBoy2CookerReqMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2CookerReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_COOKER_REQ, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendRewardMsg(long userId){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CrossCookBoy2GetRecordMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2GetRecordMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setUserId(userId);
//		reqMsg.setServerId(RelativesMgr.getUserServerId(userId));
		reqMsg.setServerId(0L);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_RECORD, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	private boolean isAbleJoinCookBoy(long userId){
		if(cookBoyDataMap.containsKey(userId)){
			return cookBoyDataMap.get(userId).isAble();
		}
		return false;
	}

	public int sendRelationMsg(long userId){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CrossCookBoy2SearchReqMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2SearchReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		Map<Long, CrossUnionMember> unionMemberMap = CrossUnionMgr.getUnionMemberMap(player.getUserInfo().getUnionUid());
		if(unionMemberMap != null){
			for(UnionMember unionMember : unionMemberMap.values()){
				if(unionMember.getUserId() != userId){
					reqMsg.addUnionList(unionMember.getUserId());
				}
			}
		}
		Map<Long, RelativesInfo> relativesMap = player.getModule(RelativesModule.class).getRelativesMap();
		for(Long reUserId : relativesMap.keySet()){
			if(relativesMap.get(reUserId).getStatus() == 1){
				reqMsg.addMarryList(reUserId);
			}
		}
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_UNION_RELATION, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public int sendSearchUserMsg(long userId,String searchId){
		//请求的时候要加上是不是进去场景的
		CookBoyProto.CookBoy2SearchOneReqMsg.Builder reqMsg = CookBoyProto.CookBoy2SearchOneReqMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setSearchId(searchId);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_SEARCH_USER, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);
		return 0;
	}

	public CookBoyData getUserCookBoyData(GamePlayer player){
		//领奖期或者重新登录了清掉道具
		if(!cookBoyDataMap.containsKey(player.getUserId())){
//			clearIntegral(player,CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId()));
			//不回收了，改成领奖期间才回收
//			clearPickUpItem(player,CookBoyActivityMgr.getCookBoy2PickUpItemId(activityInfo.getActivityId()));
			cookBoyDataMap.put(player.getUserId(),initCookBoy2(player.getUserId()));
		}else{
			reAddIntegral(player,CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId()));
		}
		return cookBoyDataMap.get(player.getUserId());
	}

	//重新加积分
	public void reAddIntegral(GamePlayer player,int itemId){
		Object locker = getLock(player.getUserId());
		synchronized (locker){
			int integralItemId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
			if(itemId == integralItemId){
				CookBoyData cookBoyData = cookBoyDataMap.get(player.getUserId());
				if(cookBoyData.getIntegral() > 0){
					player.getModule(CurrencyModule.class).addCurrency(integralItemId + "=" + cookBoyData.getIntegral(), eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2ActivityLogin);
					cookBoyData.setIntegral(0);
					synchronized (needUpdateCookBoyList){
						if(!needUpdateCookBoyList.contains(cookBoyData)){
							needUpdateCookBoyList.add(cookBoyData);
						}
					}
				}
			}
		}
	}

	public void clearIntegral(GamePlayer player,int itemId){
		Object locker = getLock(player.getUserId());
		synchronized (locker){
			int integralItemId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
			if(itemId == integralItemId){
				UserBagItem userBagItem = player.getModule(BagModule.class).getUserBagItem(integralItemId);
				if(userBagItem != null){
					player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(integralItemId + "=" + userBagItem.getNum()), eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2ActivityNewAc);
				}
			}
		}
	}

	public void clearPickUpItem(GamePlayer player,int itemId){
		Object locker = getLock(player.getUserId());
		synchronized (locker){
			int pickUpItemId = CookBoyActivityMgr.getCookBoy2PickUpItemId(activityInfo.getActivityId());
			int integralItemId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
			if(itemId == pickUpItemId){
				UserBagItem userBagPickUpItem = player.getModule(BagModule.class).getUserBagItem(pickUpItemId);
				GoodsInfo goodsInfo = GoodsMgr.getGoodsById(itemId);
				if(userBagPickUpItem != null){
					player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(pickUpItemId + "=" + userBagPickUpItem.getNum()), eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2ActivityNewAc);
					player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parseStringToProperty(integralItemId + "=" + BigInteger.valueOf(userBagPickUpItem.getNum()).multiply(goodsInfo.getParamList().get(1)).toString()), eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2ActivityNewAc);
				}
			}
		}
	}

	public PickDishRes pickDish(long userId,int times){
		PickDishRes res = new PickDishRes();
		CookBoyData cookBoyData = cookBoyDataMap.get(userId);
		if(!cookBoyData.isAble() || cookBoyData.getNo() != eActivityCookBoyType.Process2.getChildType()){
			res.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
			return res;
		}
		recoveryPickDishHp(cookBoyData);
		if(cookBoyData.getHp() - times < 0){
			res.setRet(GameErrorCode.E_COOK_BOY_MAKE_FOOD_NO_HP);
			return res;
		}

		//次数大于剩余的空位置是修正到满
		int emptyCount = 4 - cookBoyData.getProcess();
		if(times > emptyCount){
			times = emptyCount;
		}
		if(cookBoyData.getDishId() == 0){
			CookBoy2DishConfig cookBoy2DishConfig = CookBoyActivityMgr.randomPickDishId(activityInfo.getActivityId());
			cookBoyData.setDishId(cookBoy2DishConfig.getId());
		}
        cookBoyData.setHp(cookBoyData.getHp() - times);
		cookBoyData.setProcess(cookBoyData.getProcess() + times);
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		//每次挑菜的随机奖励
		List<String> randomRewardList = new ArrayList<>();
		if(times > 0){
			randomRewardList = CookBoyActivityMgr.randomPickReward(activityInfo.getActivityId(),times);
		}

		if(player != null){
			player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(), StringUtils.listToString(randomRewardList,"|"));
		}

		synchronized (needUpdateCookBoyList){
			if(!needUpdateCookBoyList.contains(cookBoyData)){
				needUpdateCookBoyList.add(cookBoyData);
			}
		}
		return res;
	}

	public PickDishRes newPickDish(long userId,int times){
		PickDishRes res = new PickDishRes();
		CookBoyData cookBoyData = cookBoyDataMap.get(userId);
		if(!cookBoyData.isAble() || cookBoyData.getNo() != eActivityCookBoyType.Process2.getChildType()){
			res.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
			return res;
		}
		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
		if(player == null){
			res.setRet(GameErrorCode.E_USER_NO_FOUND);
			return res;
		}
		//次数大于剩余的空位置是修正到满
		int emptyCount = 4 - cookBoyData.getProcess();
		if(times > emptyCount){
			times = emptyCount;
		}
		//扣体力变成扣道具
		int pickUpItemId = CookBoyActivityMgr.getCookBoy2PickUpItemId(activityInfo.getActivityId());
		Property consume =  PropertyHelper.parseStringToProperty(pickUpItemId + "=" + times);
		if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
			res.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
			return res;
		}
		player.getModule(CurrencyModule.class).removeCurrency(consume,eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2PickUpConsume);

		if(cookBoyData.getDishId() == 0){
			CookBoy2DishConfig cookBoy2DishConfig = CookBoyActivityMgr.randomPickDishId(activityInfo.getActivityId());
			cookBoyData.setDishId(cookBoy2DishConfig.getId());
		}

		cookBoyData.setProcess(cookBoyData.getProcess() + times);
		//每次挑菜的随机奖励
		List<String> randomRewardList = new ArrayList<>();
		if(times > 0){
			randomRewardList = CookBoyActivityMgr.randomPickReward(activityInfo.getActivityId(),times);
		}
		Property propertyReward = new Property();
		for(String reward : randomRewardList){
			propertyReward.addProperty(PropertyHelper.parseStringToProperty(reward));
		}
		player.getModule(CurrencyModule.class).addCurrency(propertyReward,eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2PickUpReward);
		player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(), StringUtils.listToString(randomRewardList,"|"));
		synchronized (needUpdateCookBoyList){
			if(!needUpdateCookBoyList.contains(cookBoyData)){
				needUpdateCookBoyList.add(cookBoyData);
			}
		}
		AutoLogMgr.add(new LogCookBoy2PickFood(activityInfo.getActivityId(), userId, cookBoyData.getDishId(), times, StringUtils.listToString(randomRewardList, ";"), cookBoyData.getProcess() == 4 ? 1 : 0));
		return res;
	}

	//使用体力同步体力的时候
	public void recoveryPickDishHp(CookBoyData cookBoyData){
		int recoveryTime = CookBoyActivityMgr.getCookBoy2RecoveryTime(cookBoyData.getActivityId());
		int maxHp = CookBoyActivityMgr.getCookBoy2MaxHp(cookBoyData.getActivityId());
		int hp = cookBoyData.getHp();
		long hpTime = cookBoyData.getHpTime();
		long passTime = System.currentTimeMillis() - hpTime;
		long recoveryValue = passTime/(recoveryTime*1000);
		if(hp + recoveryValue < maxHp){
			cookBoyData.setHp(hp + (int)recoveryValue);
		}else if(hp + recoveryValue >= maxHp){
			cookBoyData.setHp(maxHp);
		}
		cookBoyData.setHpTime(hpTime + recoveryValue * recoveryTime * 1000);
		synchronized (needUpdateCookBoyList){
			if(!needUpdateCookBoyList.contains(cookBoyData)){
				needUpdateCookBoyList.add(cookBoyData);
			}
		}
	}

	//合成最总成品菜
	public CookBoy2Dish dishMerge(long userId){
		CookBoy2Dish newCookBoy2Dish = null;
		Object locker = getLock(userId);
		synchronized (locker){
			CookBoyData cookBoyData = cookBoyDataMap.get(userId);
			if(cookBoyData == null){
				return null;
			}
			//还没合4下
			if(cookBoyData.getProcess() != 4){
				return null;
			}

			if(CookBoyActivityMgr.isHorseNoticeQuality(activityInfo.getActivityId(),cookBoyData.getDishId())){
				//跑马灯
				CookBoyProto.CrossCookBoy2HorseNoticeMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2HorseNoticeMsg.newBuilder();
				reqMsg.setActivityId(activityInfo.getActivityId());
				reqMsg.setUserId(userId);
				reqMsg.setDishId(cookBoyData.getDishId());
				reqMsg.setTime(System.currentTimeMillis());
				UserInfo userInfo = UserMgr.getUserInfo(userId);
				reqMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId())));
				YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_HORSE_RACE_LAMP, reqMsg);
				GamePlayerMgr.sendPacket(userId, pbMsg);
			}

			Map<Integer,CookBoy2Dish> dishMap = cookBoyData.getFinishDishMap();
			newCookBoy2Dish = new CookBoy2Dish();
			newCookBoy2Dish.setDishId(cookBoyData.getDishId());
			cookBoyData.setDishId(0);
			cookBoyData.setProcess(0);
			newCookBoy2Dish.setIndex(dishMap.size()+1);
			newCookBoy2Dish.setStatus(0);
			newCookBoy2Dish.setTime(System.currentTimeMillis());
			newCookBoy2Dish.setIntegral(0);
			newCookBoy2Dish.setTableId(0);
			dishMap.put(dishMap.size()+1,newCookBoy2Dish);
			cookBoyData.setFinishDishMap(dishMap);

			CookBoy2DishConfig cookBoy2DishConfig = CookBoyActivityMgr.getDishConfig(activityInfo.getActivityId(),newCookBoy2Dish.getDishId());

			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2MakeDishCount.getValue(),dishMap.size());
			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2MakeDishUnLock.getValue(),newCookBoy2Dish);
			UserInfo userInfo = UserMgr.getUserInfo(userId);

			cookBoyData.setAllIntegral(cookBoyData.getAllIntegral() + cookBoy2DishConfig.getScore());
			RelationActivityMgr.conditionNotify(activityInfo.getActivityId(),userId, eGamePlayerEventType.CookBoy2IntegralUserCrossRank.getValue(),
					new RelationActivityUnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(cookBoy2DishConfig.getScore()),userInfo.getUnionUid(), activityInfo.getActivityId()));
			GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
			if(player != null){
				int integralId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
				String reward = integralId + "=" + cookBoy2DishConfig.getScore();
				player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2JoinBanquetOwnerReward);
				player.getModule(CookBoyModule.class).syncSelfDishTable(activityInfo.getActivityId(),"");
			}else{
				cookBoyData.setIntegral(cookBoyData.getIntegral() + cookBoy2DishConfig.getScore());
			}

			synchronized (needUpdateCookBoyList){
				if(!needUpdateCookBoyList.contains(cookBoyData)){
					needUpdateCookBoyList.add(cookBoyData);
				}
			}
			AutoLogMgr.add(new LogCookBoy2FinishFood(activityInfo.getActivityId(), userId, newCookBoy2Dish.getIndex(), newCookBoy2Dish.getDishId(), cookBoy2DishConfig.getQuality(), 1));
		}
		return newCookBoy2Dish;
	}

	private CookBoyData initCookBoy2(long userId){
		CookBoyData temp = new CookBoyData();
		temp.setActivityId(activityInfo.getActivityId());
		temp.setUserId(userId);
		temp.setNo(activityInfo.getChildType());
		temp.setAble(CookBoyActivityMgr.isCookBoy2Able(activityInfo.getActivityId()));
		temp.setIntegral(0);
		temp.setAllIntegral(0);
		temp.setHp(CookBoyActivityMgr.getCookBoy2Hp(activityInfo.getActivityId()));
		temp.setHpTime(System.currentTimeMillis());
		temp.setFinishFoodId(0);
		temp.setTableFoodData("{}");
		temp.setFinishFoodCount(0);
		temp.setFinishFoodData("{}");
		temp.setDishId(0);
		temp.setProcess(0);
		temp.setDishCount(0);
		synchronized (needAddCookBoyList){
			if(!needAddCookBoyList.contains(temp)){
				needAddCookBoyList.add(temp);
			}
		}
		return temp;
	}

	//活动结算了没上的菜转换成活动兑换积分
	private void dishRecovery(){
		if(ActivityMgr.activityInRewardPeriod(activityInfo) && !acOverRecovery){
			for(Long userId : cookBoyDataMap.keySet()){
				long addAllIntegral = 0;
				CookBoyData cookBoyData = cookBoyDataMap.get(userId);
				Map<Integer,CookBoy2Dish> finshDishMap = cookBoyData.getFinishDishMap();
				int dishCount = 0;
				int seatCount = 0;
				for(CookBoy2Dish cookBoy2Dish : finshDishMap.values()){
					if(cookBoy2Dish.getStatus() == 3)return;//有结算过的就是跑过了
					if(cookBoy2Dish.getStatus() == 0){
						CookBoy2DishConfig cookBoy2DishConfig = CookBoyActivityMgr.getDishConfig(activityInfo.getActivityId(),cookBoy2Dish.getDishId());
						CookBoy2Spoon cookBoy2Spoon = CookBoyActivityMgr.getCookBoy2MinSpoon(activityInfo.getActivityId());
						long recoveryIntegral = cookBoy2DishConfig.getSeat() * cookBoy2Spoon.getUserIntegral();
						addAllIntegral += recoveryIntegral;
						cookBoy2Dish.setStatus(3);
						dishCount++;
						seatCount = seatCount + cookBoy2DishConfig.getSeat();
					}
				}
				if(addAllIntegral > 0){
					cookBoyData.setFinishDishMap(finshDishMap);
					int integralItemId = CookBoyActivityMgr.getCookBoy2IntegralItemId(activityInfo.getActivityId());
					UserInfo userInfo = UserMgr.getUserInfo(userId);
					String mailTitle = MultipleLanguageMgr.getContent(MailManager.COOK_BOY2_FOOD_RECOVERY_TITLE, userInfo.getLanguage());
					String mailContent = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.COOK_BOY2_FOOD_RECOVERY_CONTENT, userInfo.getLanguage()),
							dishCount,seatCount,addAllIntegral);
					MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), integralItemId + "=" + addAllIntegral, mailContent, mailTitle);
					/*GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
					if(player != null){
						player.getModule(CurrencyModule.class).addCurrency(integralItemId + "=" + addAllIntegral,eLogMoneyType.CookBoy,eLogMoneyType.CrossCookBoy2RecoverDish);
					}else{
						//不在线就放着了，登录了放进他的背包，登录的时候查过期活动这个人是否有未领取的直接load库
						cookBoyData.setIntegral(cookBoyData.getIntegral() + addAllIntegral);
					}*/
					synchronized (needUpdateCookBoyList){
						if(!needUpdateCookBoyList.contains(cookBoyData)){
							needUpdateCookBoyList.add(cookBoyData);
						}
					}
				}

			}
			acOverRecovery = true;
		}
	}

	public void timerTask(){
		dishRecovery();
		long now = System.currentTimeMillis();
		if (now - lastChekDishStatusTime > 60 * 1000L) {
			lastChekDishStatusTime = now;
			checkServerDishStatus();
		}
	}

	public boolean init() {
		return reload();
	}

	public boolean stop() {
		return false;
	}

	public boolean save() {
		List<CookBoyData> tempAddList;
		synchronized (needAddCookBoyList) {
			tempAddList = new ArrayList<>(needAddCookBoyList);
			needAddCookBoyList.clear();
		}
		if (tempAddList.size() > 0) {
			UserCookBoyBussiness.addUserCooBoyList(tempAddList);
		}
		//保存记录
		List<CookBoyData> tempUpdataList;
		synchronized (needUpdateCookBoyList) {
			tempUpdataList = new ArrayList<>(needUpdateCookBoyList);
			needUpdateCookBoyList.clear();
		}
		if (tempUpdataList.size() > 0) {
			UserCookBoyBussiness.updateUserCookBoyList(tempUpdataList);
		}

		for (CookBoy2AutoJoinSpoon spoon : autoJoinSpoonMap.values()) {
			if (spoon.isUpdateOption()) {
				new UserCommonActivityDataDaoImpl<CookBoy2AutoJoinSpoon>().update(spoon);
			} else if (spoon.isInsertOption()) {
				new UserCommonActivityDataDaoImpl<CookBoy2AutoJoinSpoon>().add(spoon);
			}
		}
		return true;
	}

	public ActivityInfo getActivityInfo(){
		return activityInfo;
	}

	public boolean reload() {
		cookBoyDataMap = UserCookBoyBussiness.getUserCookBoyMap(activityInfo.getActivityId());

		autoJoinSpoonMap = new UserCommonActivityDataDaoImpl<CookBoy2AutoJoinSpoon>().
				getActivityUserData(CookBoy2AutoJoinSpoon.class, activityInfo.getActivityId());
		return true;
	}

	public void setActivityInfo(ActivityInfo activityInfo){
		this.activityInfo = activityInfo;
	}

	public boolean isUserCookBoy2Able(long userId) {
		if(cookBoyDataMap.containsKey(userId)){
			return cookBoyDataMap.get(userId).isAble();
		}
		return false;
	}

	public void checkServerDishStatus() {
		Map<Long, List<CookBoy2Dish>> needCheckMap = new HashMap<>();
		for (CookBoyData cookBoyData : new ArrayList<>(cookBoyDataMap.values())) {
			List<CookBoy2Dish> servingDishList = new ArrayList<>();
			Map<Integer, CookBoy2Dish> finishDishMap = cookBoyData.getFinishDishMap();
			for (CookBoy2Dish dish : new ArrayList<>(finishDishMap.values())) {
				if (dish.getStatus() == 1) {
					servingDishList.add(dish);
				}
			}
			if (servingDishList.isEmpty()) {
				continue;
			}
			needCheckMap.put(cookBoyData.getUserId(), servingDishList);
		}
		if (needCheckMap.isEmpty()) {
			return;
		}
		CookBoyProto.CheckCookBoy2DishStatusMsg.Builder reqMsg = CookBoyProto.CheckCookBoy2DishStatusMsg.newBuilder();
		reqMsg.setActivityId(activityInfo.getActivityId());
		for (Map.Entry<Long, List<CookBoy2Dish>> entry : needCheckMap.entrySet()) {
			Long userId = entry.getKey();
			List<CookBoy2Dish> dishList = entry.getValue();
			for (CookBoy2Dish dish : dishList) {
				CookBoyProto.NeedCheckCookBoy2DishMsg.Builder msg = CookBoyProto.NeedCheckCookBoy2DishMsg.newBuilder();
				msg.setUserId(userId);
				msg.setDishId(dish.getTableId());
				reqMsg.addDish(msg);
			}
		}
		YanQuMessage message = YanQuMessageUtils.buildMessage(CrossProtocol.C_CROSS_COOK_BOY2_CHECK_FOOD_STATUS, reqMsg);
		GamePlayerMgr.sendPacket(0, message);
	}

	/**
	 * 获取自动回访汤勺
	 *
	 * @param userId 用户ID
	 * @return ret
	 */
	public int getAutoJoinRecord(long userId) {
		CookBoyProto.CrossCookBoy2GetAutoJoinRecordMsg.Builder reqMsg =
				CookBoyProto.CrossCookBoy2GetAutoJoinRecordMsg.newBuilder();

		reqMsg.setActivityId(activityInfo.getActivityId());
		reqMsg.setUserId(userId);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_GET_AUTO_JOIN_RECORD, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);

		return 0;
	}

	/**
	 * 设置自动回访汤勺
	 *
	 * @param activityId 活动ID
	 * @param userId     用户ID
	 * @param spoons     汤勺
	 * @return ret
	 */
	public int setAutoJoinSpoon(int activityId, long userId, List<CookBoyProto.CookBoy2SpoonTempMsg> spoons) {
		CookBoyProto.CookBoy2SetAutoJoinSpoonRespMsg.Builder respMsg =
				CookBoyProto.CookBoy2SetAutoJoinSpoonRespMsg.newBuilder();
		respMsg.setRet(0);
		if (!autoJoinSpoonMap.containsKey(userId)) {
			respMsg.setRet(GameErrorCode.E_COOK_BOY2_GET_AUTO_JOIN_SPOON_FAIL);
		}

		GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);

		Property deducts = new Property();
		Property returns = new Property();
		Object locker = getLock(userId);
		synchronized (locker) {
			CookBoy2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
			ConcurrentHashMap<Integer, Integer> spoonMap = autoJoinSpoon.getSpoonMap();
			ConcurrentHashMap<Integer, Integer> tmpSpoonMap = new ConcurrentHashMap<>(spoonMap);
			List<Integer> confSpoonIds = CookBoyActivityMgr.getCookBoy2SpoonIdList(activityId);
			for (CookBoyProto.CookBoy2SpoonTempMsg spoon : spoons) {
				int spoonId = spoon.getId();
				int oriSpoonCnt = spoonMap.get(spoonId);
				int diff = spoon.getCnt();
				if (!confSpoonIds.contains(spoonId)) { // 汤勺ID不存在
					return GameErrorCode.E_COOK_BOY2_SPOON_NOT_FOUND;
				}
				if (diff > 0) {
					deducts.addProperty(spoonId, diff);
				} else if (diff < 0) { // 取消或减少自动回访汤勺数量的设置，将差额用邮件发送
					if (oriSpoonCnt < Math.abs(diff)) { // 现有的值不够减，别扣到0，直接设置错误码
						return GameErrorCode.E_COOK_BOY2_AUTO_JOIN_SPOON_NOT_ENOUGH;
					}
					returns.addProperty(spoonId, Math.abs(diff));
				}
				tmpSpoonMap.merge(spoonId, diff, Integer::sum);
			}
			autoJoinSpoon.setSpoonMap(tmpSpoonMap);
		}

		if (!returns.isNothing()) { // 处理取消设置返还的汤勺
			UserInfo userInfo = UserMgr.getUserInfo(userId);
			String language = LanguageType.LANGUAGE_DEFAULT;
			if (null != userInfo) {
				language = userInfo.getLanguage();
			}
			String title = MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_TITLE_2, language);
			String content = MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_CONTENT_2, language);
			MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), returns.toHelperString(), content, title);
		}

		if (!deducts.isNothing()) { // 实际扣除新增的回访道具
			if (!player.getModule(CurrencyModule.class).removeCurrency(deducts, eLogMoneyType.CookBoy,
					eLogMoneyType.CrossCookBoy2AutoJoinDeduct)) {
				return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
			}
		}

		CookBoyProto.CrossCookBoy2SyncAutoJoinSpoonMsg.Builder reqMsg = CookBoyProto.CrossCookBoy2SyncAutoJoinSpoonMsg.newBuilder();
		if (autoJoinSpoonMap.containsKey(userId)) {
			CookBoy2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
			for (Map.Entry<Integer, Integer> kv : autoJoinSpoon.getSpoonMap().entrySet()) {
				CookBoyProto.CookBoy2SpoonTempMsg.Builder spoonTemp =
						CookBoyProto.CookBoy2SpoonTempMsg.newBuilder();
				spoonTemp.setId(kv.getKey());
				spoonTemp.setCnt(kv.getValue());
				respMsg.addSpoon(spoonTemp);
				reqMsg.addSpoon(spoonTemp);
			}
		}
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_COOK_BOY2_SET_AUTO_JOIN_SPOON, respMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);

		reqMsg.setActivityId(activityId);
		reqMsg.setUserId(userId);
		YanQuMessage pbMsg1 = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_SYNC_AUTO_JOIN_SPOON, reqMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg1);

		return 0;
	}

	/**
	 * 获取自动回访记录
	 *
	 * @param activityId 活动ID
	 * @param userId     用户ID
	 * @return ret
	 */
	public int getAutoJoinSpoon(int activityId, long userId) {
		CookBoyProto.CookBoy2GetAutoJoinSpoonRespMsg.Builder respMsg =
				CookBoyProto.CookBoy2GetAutoJoinSpoonRespMsg.newBuilder();

		respMsg.setRet(0);
		List<Integer> spoonIds = CookBoyActivityMgr.getCookBoy2SpoonIdList(activityId);
		if (!autoJoinSpoonMap.containsKey(userId)) { // 没有记录时初始化
			CookBoy2AutoJoinSpoon tmp = new CookBoy2AutoJoinSpoon(activityId, userId, 0);
			ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
			for (Integer spoonId : spoonIds) {
				map.put(spoonId, 0);
			}
			tmp.setSpoonMap(map);
			autoJoinSpoonMap.put(userId, tmp);
		}
		CookBoy2AutoJoinSpoon autoJoinSpoon = autoJoinSpoonMap.get(userId);
		Map<Integer, Integer> spoonMap = autoJoinSpoon.getSpoonMap();

		for (Integer spoonId : spoonIds) {
			CookBoyProto.CookBoy2SpoonTempMsg.Builder spoon = CookBoyProto.CookBoy2SpoonTempMsg.newBuilder();
			spoon.setId(spoonId);
			spoon.setCnt(spoonMap.get(spoonId));
			respMsg.addSpoon(spoon);
		}

		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.U_COOK_BOY2_GET_AUTO_JOIN_SPOON, respMsg);
		GamePlayerMgr.sendPacket(userId, pbMsg);

		return 0;
	}

	/**
	 * 处理自动回访剩余的汤勺
	 *
	 * @param userId  用户ID
	 * @param records 回访记录
	 */
	public void dealAutoJoinSpoonRest(long userId, List<CookBoyProto.CookBoy2SpoonTempMsg> records) {
		if (records.size() == 3 && autoJoinSpoonMap.containsKey(userId)) { // 未自动回访的汤勺， 汤勺类型数量为3
			Property returns = new Property();
			CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(userId);
			if (spoon.getSpoonMap() != null) {
				for (Map.Entry<Integer, Integer> kv : spoon.getSpoonMap().entrySet()) {
					int spoonId = kv.getKey();
					int spoonCnt = kv.getValue();
					if (spoonCnt > 0) {
						returns.addProperty(spoonId, spoonCnt);
					}
				}
				spoon.setIsReturn(1);
				if (returns.isNothing()) { // 没有需要返还的汤勺无须发邮件
					return;
				}
			} else {
				return;
			}

			UserInfo userInfo = UserMgr.getUserInfo(userId);
			String language = LanguageType.LANGUAGE_DEFAULT;
			if (null != userInfo) {
				language = userInfo.getLanguage();
			}

			List<Integer> spoonIds = new ArrayList<>();
			Map<Integer, Integer> spoonMap = new HashMap<>();
			for (CookBoyProto.CookBoy2SpoonTempMsg record : records) { // 120463 120464 120465
				spoonIds.add(record.getId());
				spoonMap.put(record.getId(), record.getCnt());
			}
			Collections.sort(spoonIds);
			String title = MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_TITLE_1, language);
			String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_CONTENT_1, language),
					spoonMap.get(spoonIds.get(0)), spoonMap.get(spoonIds.get(1)), spoonMap.get(spoonIds.get(2)));
			MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), returns.toHelperString(), content, title);
		}
	}

	/**
	 * 开始自动回访流程
	 *
	 * @param reqMsg reqMsg
	 */
	public void startAutoJoin(CookBoyProto.CrossCookBoy2AutoJoinInfoMsg reqMsg) {
		long guestId = reqMsg.getGuestId();
		int spoonId = reqMsg.getSpoonId();
		if (checkSpoonCnt(guestId, spoonId, reqMsg)) {
			logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}",
					reqMsg.getGuestActivityId(), guestId, reqMsg.getHostActivityId(), reqMsg.getHostId(), spoonId);
			return;
		}

		CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
		ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
		if (spoonMap != null && spoonMap.get(spoonId) == 0) {
			logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}",
					reqMsg.getGuestActivityId(), guestId, reqMsg.getHostActivityId(), reqMsg.getHostId(), spoonId);
			return;
		}

		long hostId = reqMsg.getHostId();
		CookBoyProto.CrossCookBoy2GetTasteTableCntMsg.Builder req =
				CookBoyProto.CrossCookBoy2GetTasteTableCntMsg.newBuilder();
		req.setActivityId(reqMsg.getHostActivityId());
		req.setAutoJoinInfo(reqMsg);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_GET_TASTE_TABLE_CNT, req);
		GamePlayerMgr.sendPacket(guestId, pbMsg);
	}

	/**
	 * 检查自动回访的汤勺是否足够
	 *
	 * @param userId  用户ID
	 * @param spoonId 汤勺ID
	 * @return ret
	 */
	private boolean checkSpoonCnt(long userId, int spoonId, CookBoyProto.CrossCookBoy2AutoJoinInfoMsg autoJoinInfo) {
		int guestActivityId = autoJoinInfo.getGuestActivityId();
		int hostActivityId = autoJoinInfo.getHostActivityId();
		long guestId = autoJoinInfo.getGuestId();
		long hostId = autoJoinInfo.getHostId();
		if (!autoJoinSpoonMap.containsKey(userId)) { // todo 会不会太频繁了
			logger.info("访客未设置自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", guestActivityId, guestId,
					hostActivityId, hostId, spoonId);
			return true;
		}

		CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(userId);
		ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
		if (spoonMap == null || !spoonMap.containsKey(spoonId)) {
			logger.info("访客未设置该类型的自动回访汤勺，无法自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", guestActivityId,
					guestId, hostActivityId, hostId, spoonId);
			return true;
		}

		return spoonMap.get(spoonId) <= 0;
	}

	/**
	 * 正式进行试吃
	 *
	 * @param reqMsg reqMsg
	 */
	public void autoJoinTaste(CookBoyProto.CrossCookBoy2SyncTasteTableCntMsg reqMsg) {
		CookBoyProto.CrossCookBoy2AutoJoinInfoMsg autoJoinInfo = reqMsg.getAutoJoinInfo();
		int cnt = reqMsg.getCnt();
		long guestId = autoJoinInfo.getGuestId();
		int spoonId = autoJoinInfo.getSpoonId();

		Object lock = getLock(guestId);
		CookBoyProto.CrossCookBoy2AutoJoinTasteMsg.Builder req =
				CookBoyProto.CrossCookBoy2AutoJoinTasteMsg.newBuilder();
		long hostId = autoJoinInfo.getHostId();
		synchronized (lock) {
			if (checkSpoonCnt(guestId, spoonId, autoJoinInfo)) {
				return;
			}

			if (cnt == 0) {
				logger.info("摊主可试吃数量为0，结束自动回访。 访客活动ID:{} 访客ID:{} 摊主活动ID:{} 摊主ID:{} 汤勺ID:{}", autoJoinInfo.getGuestActivityId(),
						guestId, autoJoinInfo.getHostActivityId(), autoJoinInfo.getHostId(), spoonId);
				return;
			}

			CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
			ConcurrentHashMap<Integer, Integer> spoonMap = spoon.getSpoonMap();
			int spoonCnt = Math.min(spoonMap.get(spoonId), cnt); // 玩家汤勺数和可试吃数取最小值
			// 预扣除汤勺数，正式自动回访
			spoon.modifySpoonCnt(spoonId, -spoonCnt);
			req.setSpoonCnt(spoonCnt);
		}
		req.setActivityId(autoJoinInfo.getHostActivityId());
		req.setAutoJoinInfo(autoJoinInfo);
		req.setGuestServerId(GameServer.getInstance().getServerId());
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_AUTO_JOIN_TASTE, req);
		GamePlayerMgr.sendPacket(hostId, pbMsg);
	}

	/**
	 * 处理自动回访数据
	 *
	 * @param reqMsg reqMsg
	 */
	public void dealAutoJoinResult(CookBoyProto.CrossCookBoy2SyncAutoJoinResultMsg reqMsg) {
		CookBoyProto.CrossCookBoy2AutoJoinInfoMsg autoJoinInfo = reqMsg.getAutoJoinInfo();

		long guestId = autoJoinInfo.getGuestId();
		if (reqMsg.hasRestCnt()) { // 归还未使用的汤勺
			int restCnt = reqMsg.getRestCnt();
			int spoonId = autoJoinInfo.getSpoonId();
			if (autoJoinSpoonMap.containsKey(guestId)) {
				CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
				spoon.modifySpoonCnt(spoonId, restCnt);
			} else {
				logger.error("有剩余汤勺的情况下，自动回访设置的汤匙数据不应该为空 活动ID:{} 访客ID:{} 剩余汤勺:{}",
						autoJoinInfo.getGuestActivityId(), guestId, restCnt);
			}
		}

		CookBoyProto.CrossCookBoy2SyncAutoJoinDataMsg.Builder req =
				CookBoyProto.CrossCookBoy2SyncAutoJoinDataMsg.newBuilder();
		req.setAutoJoinInfo(autoJoinInfo);
		req.setActivityId(autoJoinInfo.getGuestActivityId());

		// 汤勺数量同步到跨服
		if (autoJoinSpoonMap.containsKey(guestId)) {
			CookBoy2AutoJoinSpoon spoon = autoJoinSpoonMap.get(guestId);
			for (Map.Entry<Integer, Integer> kv : spoon.getSpoonMap().entrySet()) {
				CookBoyProto.CookBoy2SpoonTempMsg.Builder spoonTemp =
						CookBoyProto.CookBoy2SpoonTempMsg.newBuilder();
				spoonTemp.setId(kv.getKey());
				spoonTemp.setCnt(kv.getValue());
				req.addSpoon(spoonTemp);
			}
		}

		// 去跨服生成自动回访记录
		req.setRealCnt(reqMsg.getRealCnt());

		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_COOK_BOY2_SYNC_AUTO_JOIN_DATA, req);
		GamePlayerMgr.sendPacket(guestId, pbMsg);
	}

	/**
	 * 自动回访收益发邮件
	 *
	 * @param userId  用户ID
	 * @param reward  收益
	 * @param spoonId 汤勺ID
	 * @param count   回访次数
	 */
	public void dealAutoJoinReward(long userId, String reward, int spoonId, int count) {
		if (!StringUtils.isNullOrEmpty(reward)) {
			UserInfo userInfo = UserMgr.getUserInfo(userId);
			String language = LanguageType.LANGUAGE_DEFAULT;
			if (null != userInfo) {
				language = userInfo.getLanguage();
			}

			GoodsInfo goodsInfo = GoodsMgr.getGoodsById(spoonId);
			String goodsName = goodsInfo.getGoodsName();
			if (StringUtils.isNullOrEmpty(goodsName)) {
				goodsName = "";
			}
			String spoonName = ServerLanguageMgr.getContent(goodsName, language);
			Property property = PropertyHelper.parseStringToProperty(reward).goodCountMultiNum(count);
			String title = MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_TITLE_3, language);
			String content = StringUtils.format(MultipleLanguageMgr.getContent(MailManager.COOKBOY_MAIL_CONTENT_3, language), spoonName, count);
			MailManager.sendMail(userId, eMailType.DAILY.getValue(), property.toHelperString(), content, title);
		}
	}
}
